namespace Plugins.Engine
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;

    using Plugins.Interfaces;
    using Plugins.Serializer;
    using System.Xml.Serialization;

    [Serializable]
    public class PluginPropertyValue : IPluginProperty//, IPluginInitializable<PluginPropertyValue>
    {
        //private Type _type;
        
        private PluginPropertyValue _instance;
        
        private string _name;
        private string _value;

        [SuppressMessage("Microsoft.Usage", "CA2211")]
        [SuppressMessage("Microsoft.Security", "CA2104")]
        public static readonly IPluginRuntimeFormatter PluginPropertyValueXmlFormatter = new XmlFormatter();
        
        public override string ToString()
        {
            return string.Format(CultureInfo.InvariantCulture, "{0} : {1}", Name, Value);
        }

        protected PluginPropertyValue RuntimeObject { get { return _instance; } }

        public PluginPropertyValue()
        {
        }

        public PluginPropertyValue(PluginPropertyValue property)
        {
            this._instance = property;
        }

        public PluginPropertyValue(/*Type type, */string name, string value)
        {
            //this._type = type;
            this._name = name;
            this._value = value;
        }

        //public void Initialize(PluginPropertyValue obj)
        //{
        //    this._instance = obj._instance;
        //    this._type = obj._type;
        //    this._name = obj._name;
        //    this._value = obj._value;
        //}

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public static PluginPropertyValue Create<T>(string propertyName)
        {
            return new PluginPropertyValue(/*typeof(PluginPropertyValue<T>), */propertyName, PluginPropertyConverter.ConvertToString<T>(default(T)));
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public static PluginPropertyValue Create<T>(string propertyName, T defaultValue)
        {
            return new PluginPropertyValue(/*typeof(PluginPropertyValue<T>), */propertyName, PluginPropertyConverter.ConvertToString<T>(defaultValue));
        }

        [SuppressMessage("Microsoft.Design", "CA1004")]
        public static PluginPropertyValue Create<T>(string propertyName, T defaultValue, IPluginPropertyConverter<T> converter)
        {
            if (converter != null)
            {
                return new PluginPropertyValue(/*typeof(PluginPropertyValue<T>), */propertyName, converter.ConvertToString(defaultValue));
            }
            return Create<T>(propertyName, defaultValue);
        }

        public string Name
        {
            get
            {
                if (this._instance != null)
                {
                    return this._instance._name;
                }
                return this._name;
            }
            set
            {
                if (this._instance != null)
                {
                    this._instance._name = value;
                }
                else
                {
                    this._name = value;
                }
            }
        }

        public string Value
        {
            get
            {
                if (this._instance != null)
                {
                    return this._instance._value;
                }
                return this._value;
            }
            set
            {
                if (this._instance != null)
                {
                    this._instance._value = value;
                }
                else
                {
                    this._value = value;
                }
            }
        }

        private class XmlFormatter : PluginTypeSerializer<PluginPropertyValue>
        {
            public override void AddOverrides(IPluginTypeFormatter formatter)
            {
                base.AddType(formatter, "property");
                base.AddElement(formatter, "Name", "name");
                base.AddElement(formatter, "Value", "value");
                base.AddOverrides(formatter, typeof(PluginActivationData), attributes =>
                {
                    XmlTypeAttribute type = new XmlTypeAttribute("plugin");
                    if (attributes.XmlType == null)
                    {
                        attributes.XmlType = type;
                    }
                });
            }
        }
    }
}
